<?php

namespace App\Repositories;

use App\Enums\MallEnum;
use App\Exceptions\BasicException;
use App\Response\Response;
use Illuminate\Support\Facades\DB;

class MallProductsRepository
{
    /**
     * 商城产品列表
     * @param $where_product
     * @param $where_price
     * @param $page
     * @param $perPage
     * @return bool
     */
    public function productList($where_product, $where_price, $page = 1, $perPage = 20)
    {
        $product_ids = [];

        $mall_product_list = app('model_mall_products')->where($where_product)->get();
        if (!$mall_product_list->isEmpty()) {
            $prices = [];
            $ids = $mall_product_list->pluck('id')->toArray();
            if (!empty($ids)) {
                $product_ids = array_flip($ids);
                $tmp_where = $where_price;
                $price_list = app('model_mall_products_price')->where($tmp_where)->whereIn('id', $ids)->get();
                if (!$price_list->isEmpty()) {
                    foreach ($price_list as $key => $val) {
                        $prices[$val->product_id] = $val->product_id;
                    }
                }
            }
            if (!empty($where_price)) {
                foreach ($ids as $id) {
                    if (!isset($prices[$id])) {
                        unset($product_ids[$id]);
                    }
                }
            }
        }
        if ($product_ids) {
            $list = app('model_mall_products')
                ->whereIn('id', array_keys($product_ids))
                ->with('mall_categories:id,title as category_name')
                ->with([
                    'mall_products_price' => function ($query) use ($where_price) {
                        $query->select('id', 'product_id', 'price', 'day')->where($where_price);
                    },
                ])
                ->paginate($perPage, ['*'], '', $page);
        } else {
            $list = app('model_mall_products')
                ->where('id', '<', 0)
                ->with('mall_categories:id,title as category_name')
                ->with('mall_products_price')
                ->paginate($perPage, ['*'], '', $page);
        }

        return $list;
    }

    /**
     * 商城产品列表
     * @param $where
     * @return bool
     */
    public function productDetail($where)
    {
        $detail = app('model_mall_products')
            ->where($where)
            ->with('mall_products_price')
            ->first();

        return $detail;
    }

    /**
     * 新增产品
     * @param $param
     * @return bool
     * @throws BasicException
     */
    public function addProduct($param)
    {
        $add = app('model_mall_products')->create($param);
        if ($add) {
            return $add;
        }
        throw new BasicException(93106);
    }

    /**
     * 编辑产品
     * @param $param
     */
    public function saveProduct($param)
    {
        app('model_mall_products')->where('id', $param['id'])->update($param);
    }

    /**
     * 删除产品
     * @param $param
     * @return bool
     * @throws BasicException
     */
    public function delProduct($param)
    {
        $del = app('model_mall_products')->whereIn('id', $param)->delete();
        if ($del) {
            return $del;
        }
        throw new BasicException(93109);
    }

    //新增或编辑商品（新版本商城）
    public function addOrEdit($param)
    {
        $id = $param['id'] ?? 0;

        $productCateId = $param['cate_id']; //商品分类id
        $productSubCateId = $param['sub_cate_id']; //商品子分类id
        $productName = $param['product_name']; //商品名称
        $productDesc = $param['product_desc'] ?? ''; //商品介绍
        $picture = $param['picture']; //商品图片
        $special = $param['special'] ?? ''; //商品特效
        $showType = $param['show_type'] ?? 0; //展示位置
        $styleIds = explode(',', $param['style_ids']); //风格标签id
        $isBuyable = $param['is_buyable']; //是否可购买
        $rarityTagId = $param['rarity_tag_id'] ?? 0; //稀有度标签id
        $saleStatus = $param['sale_status']; //销售状态

        //可购买的商品有购买天数和对应价格，不可购买的商品有获得渠道和获得条件
        if ($isBuyable == 1) {
            $daysPrice = explode(';', $param['days_price']); //天数与价格
        } else {
            $getChannel = $param['get_channel'] ?? ''; //获得渠道
            $getCondition = $param['get_condition'] ?? ''; //获得条件
        }
        if ($rarityTagId > 0) {
            $rarityTag = app('model_product_rarity_tag')->select('id')->where('id', $rarityTagId)->first();
            if (empty($rarityTag)) throw new BasicException(0, '稀有度id不存在');
        }

        if ((($productCateId == MallEnum::PRODUCT_CATE_ID_INTO_ROOM_SPECIAL ||
                    $productCateId == MallEnum::PRODUCT_CATE_ID_NICKNAME_SPECIAL ||
                    $productCateId == MallEnum::PRODUCT_CATE_ID_BUBBLE_CHAT ||
                    $productCateId == MallEnum::PRODUCT_CATE_ID_BUBBLE_SCREEN ||
                    $productCateId == MallEnum::PRODUCT_CATE_ID_SYSTEM_BROADCAST) && $showType == 2
            ) && is_null(json_decode($special))
        ) {
            throw new BasicException(0, '入场特效、昵称特效、气泡、全服广播的特效必须传json字符串');
        }
        if($productCateId == MallEnum::PRODUCT_CATE_ID_INTO_ROOM_SPECIAL){  //入场特效仅旧版
            if($showType != 1){
                throw new BasicException(0, '入场特效仅支持旧版');
            }

        }

        $exist = app('model_mall_category_join')
            ->select('id')
            ->where('category_id', $productCateId)->where('sub_category_id', $productSubCateId)
            ->first();
        if (empty($exist)) throw new BasicException(0, '分类与子分类不匹配');

        DB::beginTransaction();
        try {
            //插入或更新商品表
            $productData = [
                'category_id' => $productCateId,
                'title' => $productName,
                'picture' => $picture,
                'special' => $special,
                'show_type' => $showType,
                'on_sale' => $saleStatus == 1 ? 1 : 2,
                'desc' => $productDesc,
                'sub_cate_id' => $productSubCateId,
                'is_buyable' => $isBuyable,
                'rarity_tag_id' => $rarityTagId,
                'update_time' => time(),
            ];
            if ($isBuyable == 0) {
                $productData['get_channel'] = $getChannel;
                $productData['get_condition'] = $getCondition;
            }

            if ($id > 0) { //编辑

                $product = app('model_mall_products')->select('discount_rate', 'is_recommend', 'on_sale')->where('id', $id)->first();
                if (empty($product)) {
                    throw new BasicException(0, '商品id错误，商品不存在');
                }
                //下架的时候如果是推荐商品则取消推荐，保证下架的商品不可能是推荐商品
                if ($product->on_sale == 1 && $saleStatus == 0 && $product->is_recommend == 1) {
                    $productData['is_recommend'] = 0;
                }

                //更新商品
                app('model_mall_products')->where('id', $id)->update($productData);

                //查询原来的商品与风格标签的关联
                $originalStyleIds = app('model_product_style_join')
                    ->select('style_id')
                    ->where('product_id', $id)
                    ->pluck('style_id')->toArray();

                //查询原始天数和价格的映射
                if ($isBuyable == 1) {
                    $originalDaysPrice = app('model_mall_products_price')
                        ->select(DB::raw("CONCAT_WS(':', day, price) as days_price"))
                        ->where('product_id', $id)
                        ->pluck('days_price')->toArray();
                }

            } else { //新增

                $originalStyleIds = [];
                $originalDaysPrice = [];
                $productData['add_time'] = time();
                $id = app('model_mall_products')->insertGetId($productData);
            }

            //要插入的商品与风格标签关联
            $insertStyleIds = array_diff($styleIds, $originalStyleIds);
            foreach ($insertStyleIds as $insertStyleId) {
                app('model_product_style_join')->insert([
                    'product_id' => $id,
                    'style_id' => $insertStyleId
                ]);
            }
            //要删除的商品与风格标签关联
            $delStyleIds = array_diff($originalStyleIds, $styleIds);
            foreach ($delStyleIds as $delStyleId) {
                app('model_product_style_join')->where([
                    'product_id' => $id,
                    'style_id' => $delStyleId
                ])->delete();
            }

            //商品天数价格维护
            if ($isBuyable == 1) {

                //要新增的天数价格
                $insertDaysPrices = array_diff($daysPrice, $originalDaysPrice);
                foreach ($insertDaysPrices as $insertDaysPrice) {
                    list($days, $price) = explode(':', $insertDaysPrice);
                    //天数和价格合法性验证
                    $this->daysPriceVerify($days, $price);
                    $days = $days == -1 ? 9999 : $days;
                    app('model_mall_products_price')->insert([
                        'product_id' => $id,
                        'day' => $days,
                        'price' => $price,
                        'original_price' => $price,
                    ]);
                }

                //要删除的天数价格
                $delDaysPrices = array_diff($originalDaysPrice, $daysPrice);
                foreach ($delDaysPrices as $delDaysPrice) {
                    list($days, $price) = explode(':', $delDaysPrice);
                    $days = $days == -1 ? 9999 : $days;
                    $daysPrice = app('model_mall_products_price')
                        ->select('id')
                        ->where('product_id', $id)
                        ->where('day', $days)
                        ->first();

                    //检测天数价格是否存在已实现的心愿单
                    $wish = app('model_mall_wishlist')
                        ->select('id')
                        ->where('price_id', $daysPrice->id)
                        ->where('status', 1)
                        ->first();
                    if ($wish) {
                        throw new BasicException(0, "商品天数价格有已实现的心愿单，不能删除，{$days}天");
                    }

                    //删除未实现的心愿单
                    app('model_mall_wishlist')
                        ->where('price_id', $daysPrice->id)->where('status', 0)
                        ->delete();

                    $daysPrice->delete();
                }
            }

            DB::commit();
            return Response::sendData([]);
        } catch (\Exception $e) {
            DB::rollBack();
            throw new BasicException(0, $e->getMessage());
        }
    }

    //天数价格转为特定格式的数组
    private function daysPriceVerify($days, $price)
    {
        if ($price < 100) throw new BasicException(0, '价格不能小于100金币');
        if (!is_numeric($days) || ($days < 1 && $days != -1) ||
            !is_numeric($price)) {
            throw new BasicException(0, '参数错误，天数与价格');
        }
    }

    //获取商品列表（新版本商城，单品、套装等）
    public function getList($param)
    {
        $group = $param['group'] ?? 1; //1：单品；2：套装
        $isRarity = $param['is_rarity'] ?? -1; //是否稀有商品，-1：不限制；1：是；0：否
        $isDiscount = $param['is_discount'] ?? -1; //是否折扣商品，-1：不限制；1：是；0：否
        $isRecommend = $param['is_recommend'] ?? -1; //是否推荐，-1：不限制；1：是；0：否
        $cateId = $param['cate_id'] ?? 0; //分类id
        $subCateId = $param['sub_cate_id'] ?? 0; //子分类id
        $name = $param['name'] ?? ''; //商品名称
        $days = $param['days'] ?? 0; //天数
        $originalPrice = $param['original_price'] ?? 0; //原始价格
        $styleId = $param['style_id'] ?? 0; //风格标签id
        $status = $param['status'] ?? -1; //状态
        $addDate = $param['add_date'] ?? ''; //添加日期
        $pageSize = $param['page_size'] ?? 10;

        $where = [];
        $whereFunc1 = $whereFunc2 = $whereFunc3 = $whereFunc4 = [];
        if ($isRarity == 1) {
            $where[] = ['rarity_tag_id', '>', 0];
        } else if ($isRarity == 0) {
            $where[] = ['rarity_tag_id', '=', 0];
        }
        if ($isDiscount == 1) {
            $where[] = ['discount_rate', '<', 100];
        } else if ($isDiscount == 0) {
            $where[] = ['discount_rate', '=', 100];
        }
        if ($isRecommend != -1) {
            $where[] = ['is_recommend', '=', $isRecommend];
        }
        if ($cateId > 0) {
            $where[] = ['category_id', '=', $cateId];
        }
        if ($subCateId > 0) {
            $where[] = ['sub_cate_id', '=', $subCateId];
        }
        if ($name) {
            $where[] = ['title', 'like', "%$name%"];
        }
        //天数
        if ($days) {
            $productIds = app('model_mall_products_price')
                ->select('product_id')
                ->where('day', $days)
                ->pluck('product_id')->toArray();
            $whereFunc1 = function ($query) use ($productIds) {
                $query->whereIn('id', $productIds);
            };
        }
        //价格
        if ($originalPrice) {
            $productIds = app('model_mall_products_price')
                ->select('product_id')
                ->where('original_price', $originalPrice)
                ->pluck('product_id')->toArray();
            $whereFunc2 = function ($query) use ($productIds) {
                $query->whereIn('id', $productIds);
            };
        }
        //风格标签id
        if ($styleId) {
            //查询风格id下的所有商品id
            $productIds = app('model_product_style_join')
                ->select('product_id')
                ->where('style_id', $styleId)
                ->pluck('product_id')->toArray();
            $whereFunc3 = function ($query) use ($productIds) {
                $query->whereIn('id', $productIds);
            };
        }
        //出售状态
        if ($status != -1) {
            $onSale = $status == 0 ? 2 : 1;
            $where[] = ['on_sale', '=', $onSale];
        }
        //添加日期
        if ($addDate) {
            $where[] = ['add_time', '>=', strtotime($addDate . ' 0:0:0')];
            $where[] = ['add_time', '<=', strtotime($addDate . ' 23:59:59')];
        }
        //排除人脉商品
        $where[] = ['module', '<>', 1];

        //单品或套装
        if ($group == 1) {
            $cates = app('model_mall_categories')->getCategories([['id', '<>', MallEnum::PRODUCT_CATE_ID_SUIT], ['id', '<>', MallEnum::PRODUCT_CATE_ID_GOOD_CODE]]);
            $cates = array_column($cates, 'title', 'id');
            $categoryIds = array_keys($cates);
            $whereFunc4 = function ($query) use ($categoryIds) {
                $query->whereIn('category_id', $categoryIds);
            };
            $subCates = app('model_mall_sub_category')
                ->select('name', 'id')
                ->pluck('name', 'id')->toArray();
        } else if ($group == 2) {
            $where[] = ['category_id', '=', MallEnum::PRODUCT_CATE_ID_SUIT];
        }

        //查询所有稀有度标签
        $rarityTags = app('model_product_rarity_tag')->select('id', 'name')->pluck('name', 'id')->toArray();

        $list = app('model_mall_products')
            ->select('id', 'title as product_name', 'category_id', 'picture', 'special', 'on_sale', 'add_time', 'discount_rate', 'get_channel', 'get_condition', 'sub_cate_id', 'is_buyable', 'rarity_tag_id', 'is_recommend', 'discount_status', 'discount_sort')
            ->where($where)
            ->where($whereFunc1)
            ->where($whereFunc2)
            ->where($whereFunc3)
            ->where($whereFunc4);
        if ($isDiscount == 1) {
            $list = $list->orderByDesc('discount_sort');
        }
        $list = $list->paginate($pageSize);

        foreach ($list as &$v) {
            //类别名称
            if ($group == 1) {
                $v->cate_name = $cates[$v->category_id];
                $v->sub_cate_name = $subCates[$v->sub_cate_id] ?? '';
            }
            //查询风格标签
            $styleNames = app('model_products_style')->from('ln_products_style as ps')
                ->leftJoin('ln_product_style_join as psj', 'ps.id', '=', 'psj.style_id')
                ->select('ps.name')
                ->where('psj.product_id', $v->id)
                ->pluck('ps.name')->toArray();
            $v->style = implode(',', $styleNames);
            //添加时间
            $v->add_time = date('Y-m-d H:i:s', $v->add_time);
            //商品状态：上架或下架
            if ($v->on_sale == 1) $v->status_name = '上架';
            else $v->status_name = '下架';
            //动效
            if (empty($v->special)) $v->special = '';
            //商品天数和价格信息
            if ($v->is_buyable == 1) {
                $v->product_price = app('model_mall_products_price')
                    ->select('day', 'original_price', 'price')
                    ->where('product_id', $v->id)
                    ->get();
            }

            //如果是套装则查询下面的所有商品（商品图片）
            if ($group == 2) {
                $suitProductIds = app('model_mall_products_suit_relation')
                    ->where('suit_id', $v->id)->pluck('product_id');
                $v->suit_products = app('model_mall_products')
                    ->select('picture')->whereIn('id', $suitProductIds)->get();
            }

            //稀有度标签
            $v->rarity_tag_name = $rarityTags[$v->rarity_tag_id] ?? '';
        }

        return $list;
    }

    /*获取商品稀有度下拉框*/
    public function getRarityList()
    {
        $list = app('model_mall_categories')
            ->selectRaw('value as id,title')
            ->where('parent_id', MallEnum::PRODUCT_CATE_ID_RARITY)
            ->orderBy('sort', 'asc')
            ->get();
        return $list;
    }

    //新增或编辑套装（新版本商城）
    public function addOrEditSuit($param)
    {
        $id = $param['id'] ?? 0;
        $suitName = $param['suit_name'];
        $suitDesc = $param['suit_desc'];
        $picture = $param['picture'];
        $styleIds = $param['style_ids'];
        $productIds = $param['product_ids'];
        $daysPrice = $param['days_price'];
        $rarityTagId = $param['rarity_tag_id'] ?? 0; //稀有度标签id
        $saleStatus = $param['sale_status'] ?? 1;

        $suit = app('model_mall_products')
            ->where('title', $suitName)
            ->where(function ($query) use ($id) {
                if ($id > 0) {
                    $query->where('id', '<>', $id);
                }
            })->first();
        if ($suit) throw new BasicException(0, '套餐名称已经存在');

        if ($rarityTagId > 0) {
            $rarityTag = app('model_product_rarity_tag')->select('id')->where('id', $rarityTagId)->first();
            if (empty($rarityTag)) throw new BasicException(0, '稀有度id不存在');
        }

        DB::beginTransaction();
        try {

            //增加套装
            $suitData = [
                'category_id' => MallEnum::PRODUCT_CATE_ID_SUIT,
                'title' => $suitName,
                'desc' => $suitDesc,
                'picture' => $picture,
                'on_sale' => $saleStatus == 1 ? 1 : 2,
                'rarity_tag_id' => $rarityTagId,
                'update_time' => time(),
            ];

            if ($id > 0) {
                $suitId = $id;
                app('model_mall_products')->where('id', $id)->update($suitData);

                //删除原来的套装价格
                app('model_mall_products_price')->where('product_id', $suitId)->delete();
                //删除原来的套装关联商品记录
                app('model_mall_products_suit_relation')->where('suit_id', $suitId)->delete();
                //删除原来的套装风格关联记录
                app('model_product_style_join')->where('product_id', $suitId)->delete();

            } else {
                $suitData['add_time'] = time();
                $suitId = app('model_mall_products')->insertGetId($suitData);
            }

            //增加套装价格
            $productIds = explode(',', $productIds);
            $tmp = explode(';', $daysPrice);
            foreach ($tmp as $k => $v) {
                $tmp2 = explode(':', $v);
                if (isset($tmp2[0])) $suitDays = $tmp2[0]; //套餐天数
                else throw new BasicException(0, '参数结构错误：天数与价格');

                if (isset($tmp2[1])) $suitPrice = $tmp2[1]; //套餐价格
                else throw new BasicException(0, '参数结构错误：天数与价格');

                if (!is_numeric($suitPrice) || $suitPrice <= 0) {
                    throw new BasicException(0, "套装价格有误：{$suitPrice}");
                }

                $suitOriginalPrice = 0;
                foreach ($productIds as $productId) {
                    $product = app('model_mall_products')
                        ->select('id', 'title', 'category_id', 'on_sale')
                        ->where('id', $productId)->first();
                    if (empty($product)) throw new BasicException(0, '参数错误：商品id');
                    if ($product->on_sale == 2) throw new BasicException(0, "商品已经下架：{$product->title}");
                    //商品所属分类是否能加入套装
                    $isJoinSuit = app('model_mall_categories')
                        ->where('id', $product->category_id)->value('is_join_suit');
                    if ($isJoinSuit == 0) throw new BasicException(0, "商品：{$product->title} 不能加入套装");

                    $productPrice = app('model_mall_products_price')
                        ->select('price')
                        ->where('product_id', $productId)->where('day', $suitDays)
                        ->first();
                    if (empty($productPrice)) {
                        throw new BasicException(0, "商品：{$product->title} 没有{$suitDays}天的价格");
                    }
                    $suitOriginalPrice += $productPrice->price;
                }

                app('model_mall_products_price')->insert([
                    'product_id' => $suitId,
                    'day' => $suitDays,
                    'price' => $suitPrice,
                    'original_price' => $suitOriginalPrice,
                ]);
            }

            //增加套装与商品关联
            foreach ($productIds as $productId) {
                app('model_mall_products_suit_relation')->insert([
                    'suit_id' => $suitId,
                    'product_id' => $productId
                ]);
            }

            //增加套装与风格关联
            $styleIds = explode(',', $styleIds);
            $flag = 0;
            foreach ($styleIds as $styleId) {
                if ($styleId) {
                    $flag = 1;
                    $systemStyleId = app('model_products_style')
                        ->select('id')
                        ->where('id', $styleId)->where('is_show', 1)
                        ->first();
                    if (empty($systemStyleId)) throw new BasicException(0, '参数错误：风格标签id');
                    app('model_product_style_join')->insert(['product_id' => $suitId, 'style_id' => $styleId]);
                }
            }
            if ($flag == 0) throw new BasicException(0, '至少选择一个风格标签');

            DB::commit();
            return Response::sendData([]);
        } catch (\Exception $e) {
            DB::rollBack();
            throw new BasicException(0, $e->getMessage());
        }
    }

    //赠送礼物
    public function give($param)
    {
        $productId = $param['id'];
        $userCode = $param['user_code'];
        $useDays = $param['use_days'];

        //查询用户id
        $userId = app('repo_user_data')->getUserId(['user_code' => $userCode]);
        $userId = app("model_user")->where('user_id', $userId)->where('deleted', 0)->value('user_id');
        if (!$userId) throw new BasicException(10001, "用户不存在");

        //查询商品是否存在
        $product = app('model_mall_products')->select('title', 'category_id', 'on_sale')->where('id', $productId)->first();
        if (empty($product)) throw new BasicException(50005);

        //查询所有靓号的子分类，判断是否靓号且是否正在使用
        $goodCodeSubCategoryIds = app('model_mall_categories')->getAllSubCateId(MallEnum::PRODUCT_CATE_ID_GOOD_CODE);
        if (in_array($product->category_id, $goodCodeSubCategoryIds)) {
            $userData = app('model_user_data')->select('id')->where('user_code', $product->title)->first();
            if ($userData) throw new BasicException(0, '靓号正在使用中');
        }

        DB::beginTransaction();
        try {

            //靓号赠送成功之后必须下架
            if (in_array($product->category_id, $goodCodeSubCategoryIds)) {
                app('model_mall_products')->where('id', $productId)->update(['on_sale' => 2]);
            }

            if ($product->category_id == MallEnum::PRODUCT_CATE_ID_SUIT) { //套装
                //查询套装里的所有商品
                $suitProductIds = app('model_mall_products_suit_relation')
                    ->where('suit_id', $productId)->pluck('product_id')->toArray();
                foreach ($suitProductIds as $suitProductId) {
                    $this->toGive($userId, $suitProductId, $useDays, $productId);
                }
            } else {
                $this->toGive($userId, $productId, $useDays);
            }

            DB::commit();
        } catch (\Exception $e) {
            DB::rollBack();
            throw new BasicException(10001, '赠送失败：' . $e->getMessage());
        }
    }

    private function toGive($userId, $productId, $useDays, $suitId = 0)
    {
        //查询商品是否存在
        $product = app('model_mall_products')->select('category_id')->where('id', $productId)->first();
        if (empty($product)) throw new BasicException(50005);

        $price = app("model_mall_products_price")
            ->select('id', 'day', 'price')
            ->where('product_id', $productId)
            ->where('day', $useDays)
            ->first();

        $order = app("model_mall_orders")
            ->select('id', 'state', 'expired_time')
            ->where('product_id',  $productId)->where('user_id_owner', $userId)->first();

        if ($order) {
            if ($order->state == 2 || $order->expired_time < time()) {
                $updateData = [
                    'state' => 0,
                    'expired_time' => time() + $useDays * 86400
                ];
            } else {
                $updateData = [
                    'expired_time' => $order->expired_time + $useDays * 86400
                ];
            }
            app("model_mall_orders")->where('id' , $order->id)->update($updateData);
        } else {
            app("model_mall_orders")->create([
                'user_id_buyer' => 0,
                'user_id_owner' => $userId,
                'product_id'    => $productId,
                'price_id'      => $price->id ?? 0,
                'state'         => 0,
                'add_time'      => time(),
                'price'         => floatval($price->price ?? 0),
                'day'           => intval($price->day ?? $useDays),
                'type'          => 3,
                'expired_time'  => time() + $useDays * 86400,
                'category_id'   => $product->category_id,
                'coin'          => 0
            ]);
        }

    }

    //新增或编辑人脉商品
    public function addOrEditConnect($param)
    {
        $id = $param['id'] ?? 0;
        $categoryId = $param['category_id'];
        $productName = $param['product_name'];
        $picture = $param['picture'];
        $special = $param['special'] ?? '';
        $showType = $param['show_type'] ?? 0;
        $priceInfo = $param['price_info'];
        $saleStatus = $param['sale_status'];

        $categoryId = app('model_mall_categories')
            ->where('parent_id', MallEnum::PRODUCT_CATE_ID_ALL)
            ->where('id', $categoryId)
            ->value('id');
        if (empty($categoryId)) throw new BasicException(0, '分类id错误');

        if (($categoryId == MallEnum::PRODUCT_CATE_ID_INTO_ROOM_SPECIAL ||
                $categoryId == MallEnum::PRODUCT_CATE_ID_BUBBLE_SCREEN
            ) && is_null(json_decode($param['special']))
        ) {
            throw new BasicException(0, '特效参数错误，入场特效和公屏气泡必须是json字符串');
        }

        if (is_null($priceInfo = json_decode($priceInfo, true))) {
            throw new BasicException(0, '商品价格格式错误');
        }
        if (!isset($priceInfo['day']) || !is_numeric($priceInfo['day']) || $priceInfo['day'] <= 0) {
            throw new BasicException(0, '天数 格式错误');
        }
        if (!isset($priceInfo['price']) || !is_numeric($priceInfo['price']) || $priceInfo['price'] <= 0) {
            throw new BasicException(0, '商品价格 格式错误');
        }
        if (!isset($priceInfo['intimacy']) || !is_numeric($priceInfo['intimacy']) || $priceInfo['intimacy'] <= 0) {
            throw new BasicException(0, '亲密值 格式错误');
        }

        $data = [
            'category_id' => $categoryId,
            'title' => $productName,
            'update_time' => time(),
            'picture' => $picture,
            'special' => $special,
            'show_type' => $showType,
            'on_sale' => $saleStatus == 1 ? 1 : 2,
            'module' => MallEnum::PRODUCT_MODULE_CONNECT,
        ];

        DB::beginTransaction();
        try {
            if ($id > 0) {
                $product = app('model_mall_products')->select('id')->where('id', $id)->first();
                if (empty($product)) throw new BasicException(0, '商品id错误');

                //删除原来的商品价格
                app('model_mall_products_price')->where('product_id', $id)->delete();
                //更新商品
                app('model_mall_products')->where('id', $id)->update($data);
            } else {
                //新增商品
                $data['add_time'] = time();
                $id = app('model_mall_products')->insertGetId($data);
            }

            //新增商品价格
            app('model_mall_products_price')->insert([
                'product_id' => $id,
                'day' => $priceInfo['day'],
                'price' => $priceInfo['price'],
                'original_price' => $priceInfo['price'],
                'intimacy' => $priceInfo['intimacy'],
            ]);

            DB::commit();
            return true;
        } catch (\Exception $e) {
            DB::rollBack();
            throw new BasicException(0, $e->getMessage());
        }
    }
}
